Skip to content

代码随想录 数组:54. 区间和

题目描述

​ 给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

输入描述

​ 第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间,直至文件结束。

输出描述

​ 输出每个指定区间内元素的总和。

输入示例

text
5
1
2
3
4
5
0 1
1 3

输出示例

text
3
9

数据范围:

0 < n <= 100000

思路

在一个数组内随意划定一个区间,求和。这看起来很简单一个 for 循环就行,但是如果要求 n 次呢?岂不是又要一个 for 循环?就 o(n^2)了啊。

其实,对于数组区间和的问题,可以提前计算累计和或叫前缀和。

前缀和的思想是重复利用计算过的子数组之和,从而降低区间查询需要累加计算的次数。

有一个 vec 数组,先求出来前缀和数组 p。

例如我们想统计,在 vec 数组上 下标 2 到下标 5 之间的累加和,那是不是就用 p[5] - p[1] 就可以了。

为什么呢?

p[1] = vec[0] + vec[1];
p[5] = vec[0] + vec[1] + vec[2] + vec[3] + vec[4] + vec[5];
p[5] - p[1] = vec[2] + vec[3] + vec[4] + vec[5];

求 a 到 b 的区间和,就 p[b]-p[a-1] 就行。

cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int n, a, b;
    cin >> n;
    vector<int> vec(n);
    vector<int> p(n);
    int persum = 0;
    for (int i = 0; i < n; i++)
    {
        // cin >> vec[i];
        scanf("%d",&vec[i]);
        persum += vec[i]; // 在输入的时候就进行计算其前缀和,前缀和是累加的,每得到一个值就把他填充到前缀和数组中
        p[i] = persum;
    }
    while (cin >> a >> b)
    {
        int sum;
        if (a == 0)
            sum = p[b]; // 特殊情况,这是因为如果不设置这个判断,按照下面计算就会出现p[0-1],超出索引范围了
        else
            sum = p[b] - p[a - 1];
        // cout << sum << endl;
        printf("%d\n",sum);
    }
}